home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 10 / FM Towns Free Software Collection 10.iso / ms_dos / tool / fwcp / src / dir.c < prev    next >
Text File  |  1995-03-08  |  8KB  |  384 lines

  1. /***********************************
  2.  
  3.     Dir & File Select
  4.  
  5. **********************************/
  6. #include    <stdio.h>
  7. #include    <stdlib.h>
  8. #include    <string.h>
  9. #include    <ctype.h>
  10. #include    <jctype.h>
  11. #include    <dos.h>
  12. #include    "dir.h"
  13.  
  14. #define TRUE        1
  15. #define FALSE        0
  16. #define ERR        (-1)
  17.  
  18. static    int    sort_mode = 0;
  19. static    struct find_t    dma;
  20.  
  21. static    char    *strlowcpy(char *dis, register char *s)
  22. {
  23.     int     ch;
  24.     register char *p;
  25.  
  26.     p = dis;
  27.     while ( *s != '\0' ) {
  28.     ch = *(s++);
  29.     if ( iskanji(ch) && iskanji2(*s) ) {
  30.         *(p++) = ch;
  31.         *(p++) = *(s++);
  32.     } else if ( isupper(ch) )
  33.         *(p++) = tolower(ch);
  34.     else
  35.         *(p++) = ch;
  36.     }
  37.     *p = '\0';
  38.     return dis;
  39. }
  40. static    char    *subname(char *name)
  41. {
  42.     while ( *name != '.' && *name != '\0' )
  43.     name += (iskan(name) ? 2 : 1);
  44.     return name;
  45. }
  46. static    int    path_cmp(DIRECT *sp, DIRECT *dp)
  47. {
  48.     int cd;
  49.  
  50.     if ( (sp->d_att & AT_DIR) != (dp->d_att & AT_DIR) )
  51.     return ((sp->d_att & AT_DIR) != 0 ? (-1) : 1);
  52.  
  53.     switch(sort_mode) {
  54.     case 0:
  55.     cd = strcmp(sp->d_name,dp->d_name);
  56.     break;
  57.     case 1:
  58.     if ( (cd = strcmp(subname(sp->d_name), subname(dp->d_name))) != 0 )
  59.         break;
  60.     cd = strcmp(sp->d_name,dp->d_name);
  61.     break;
  62.     case 2:
  63.     if ( sp->d_size < dp->d_size )
  64.         cd = (-1);
  65.     else if ( sp->d_size > dp->d_size )
  66.         cd = 1;
  67.     else
  68.         cd = 0;
  69.     break;
  70.     case 3:
  71.     if ( sp->d_date < dp->d_date )
  72.         cd = (-1);
  73.     else if ( sp->d_date > dp->d_date )
  74.         cd = 1;
  75.     else if ( sp->d_time < dp->d_time )
  76.         cd = (-1);
  77.     else if ( sp->d_time > dp->d_time )
  78.         cd = 1;
  79.     else
  80.         cd = 0;
  81.     break;
  82.     }
  83.  
  84.     return cd;
  85. }
  86. static    DIRECT    *dir_sort(DIRECT *np)
  87. {
  88.     DIRECT    *tp, *bp;
  89.     DIRECT    *lp, *rp;
  90.  
  91.     if ( np == NULL || np->d_next == NULL )
  92.     return np;
  93.  
  94.     lp = rp = NULL;
  95.     tp = np->d_next;
  96.  
  97.     while ( tp != NULL ) {
  98.     bp = tp->d_next;
  99.     if ( path_cmp(np, tp) >= 0 ) {
  100.         tp->d_next = lp;
  101.         lp = tp;
  102.     } else {
  103.         tp->d_next = rp;
  104.         rp = tp;
  105.     }
  106.     tp = bp;
  107.     }
  108.  
  109.     lp = dir_sort(lp);
  110.     rp = dir_sort(rp);
  111.  
  112.     if ( lp != NULL ) {
  113.     tp = lp;
  114.     while ( lp->d_next != NULL )
  115.         lp = lp->d_next;
  116.     lp->d_next = np;
  117.     } else
  118.     tp = np;
  119.  
  120.     np->d_next = rp;
  121.  
  122.     return tp;
  123. }
  124. int    dos_stat(char *name, DIRECT *st)
  125. {
  126.     if ( _dos_findfirst(name, 0x31, &dma) )
  127.     return ERR;
  128.  
  129.     st->d_att  = dma.attrib;
  130.     st->d_time = dma.wr_time;
  131.     st->d_date = dma.wr_date;
  132.     st->d_size = dma.size;
  133.     strcpy(st->d_name, dma.name);
  134.  
  135.     while ( !_dos_findnext(&dma) )
  136.     ;
  137.  
  138.     return FALSE;
  139. }
  140. static DIRECT  *dir_get(char *sdir, int *st)
  141. {
  142.     register DIRECT *np;
  143.     char *dir;
  144.     DIRECT *top = NULL;
  145.     DIRECT *root = NULL;
  146.  
  147.     *st = FALSE;
  148.     dir = path_make(sdir, "*.*");
  149.  
  150.     if ( _dos_findfirst(dir, 0x31, &dma) )
  151.     goto ENDOF;
  152.  
  153.     do {
  154.     if ( strcmp(dma.name, ".") == 0 )
  155.         continue;
  156.  
  157.     if ( (np = (DIRECT *)malloc(sizeof(DIRECT))) == NULL ) {
  158.         message("opendir %s memory alloc error", sdir);
  159.  
  160.         while ( !_dos_findnext(&dma) )
  161.         ;
  162.         while ( top != NULL ) {
  163.         np = top->d_next;
  164.         free(top);
  165.         top = np;
  166.         }
  167.         *st = ERR;
  168.         return NULL;
  169.     }
  170.  
  171.     np->d_next = NULL;
  172.     np->d_mark = FALSE;
  173.     np->d_att  = dma.attrib;
  174.     np->d_time = dma.wr_time;
  175.     np->d_date = dma.wr_date;
  176.     np->d_size = dma.size;
  177.     strcpy(np->d_name, dma.name);
  178.  
  179.     if ( strcmp(dma.name, "..") == 0 ) {
  180.         if ( root != NULL )
  181.         free(root);
  182.         root = np;
  183.     } else {
  184.         np->d_next = top;
  185.         top = np;
  186.     }
  187.  
  188.     } while ( !_dos_findnext(&dma) );
  189.  
  190.     top = dir_sort(top);
  191.  
  192. ENDOF:
  193.  
  194.     if ( root != NULL ) {
  195.     root->d_next = top;
  196.     top = root;
  197.  
  198.     } else if ( strcmp(dir + 1, ":\\*.*") != 0 &&
  199.     (np = (DIRECT *)malloc(sizeof(DIRECT))) != NULL ) {
  200. /**********************************************
  201.     np->d_mark = FALSE;
  202.     np->d_att  = 0x10;
  203.     np->d_time = 0;
  204.     np->d_date = 0;
  205.     np->d_size = 0;
  206.     strcpy(np->d_name, "..");
  207.     np->d_next = top;
  208.     top = np;
  209. ************************************************/
  210.     if ( dos_stat(sdir, np) )
  211.         free(np);
  212.     else {
  213.         np->d_mark = FALSE;
  214.         strcpy(np->d_name, "..");
  215.         np->d_next = top;
  216.         top = np;
  217.     }
  218.     }
  219.  
  220.     return top;
  221. }
  222. DIR    *opendir(char *dir, int mode)
  223. {
  224.     int     st;
  225.     DIR     *dirp;
  226.     register DIRECT *np;
  227.  
  228.     sort_mode = mode;
  229.  
  230.     if ( (dirp = (DIR *)malloc(sizeof(DIR))) == NULL ) {
  231.     message("opendir %s ptr memory alloc error", dir);
  232.     return NULL;
  233.     }
  234.  
  235.     if ( (dirp->dd_top = dirp->dd_now = dir_get(dir, &st)) == NULL ) {
  236.     if ( st == ERR || !isdir(dir) ) {
  237.         free(dirp);
  238.         return NULL;
  239.     }
  240.     }
  241.  
  242.     return dirp;
  243. }
  244. DIRECT    *readdir(DIR *dirp)
  245. {
  246.     DIRECT *np;
  247.  
  248.     if ( (np = dirp->dd_now) != NULL )
  249.     dirp->dd_now = np->d_next;
  250.     return np;
  251. }
  252. void    seekdir(DIR *dirp,int n)
  253. {
  254.     DIRECT *np;
  255.  
  256.     np = dirp->dd_top;
  257.     while ( n-- > 0 && np != NULL )
  258.     np = np->d_next;
  259.     dirp->dd_now = np;
  260. }
  261. int    countdir(DIR *dirp)
  262. {
  263.     int n;
  264.     DIRECT *np;
  265.  
  266.     np = dirp->dd_top;
  267.     for ( n = 0 ; np != NULL ; n++ )
  268.     np = np->d_next;
  269.     return n;
  270. }
  271. void    closedir(DIR *dirp)
  272. {
  273.     DIRECT *np,*tp;
  274.  
  275.     np = dirp->dd_top;
  276.     while ( np != NULL ) {
  277.     tp = np->d_next;
  278.     free(np);
  279.     np = tp;
  280.     }
  281.     free(dirp);
  282. }
  283. int    isdir(char *dir)
  284. {
  285.     unsigned attr;
  286.  
  287.     if ( dir[0] != '\0' && dir[1] == ':' &&
  288.         (dir[2] == '\0' || (dir[2] == '\\' && dir[3] == '\0')) )
  289.     return TRUE;
  290.  
  291.     if ( _dos_getfileattr(dir, &attr) )
  292.     return FALSE;
  293.  
  294.     return ((attr & 0x10) != 0 ? TRUE:FALSE);
  295. }
  296. char    *path_make(char *dir, char *file)
  297. {
  298.     char    *p;
  299.     static char tmp[256];
  300.  
  301.     for ( p = dir ; *p != '\0' ; p++ )
  302.     ;
  303.     if ( *file == '\\' || *dir == '\0' ||
  304.     (p != dir && (*(p - 1) == ':' || *(p - 1) == '\\')) )
  305.     sprintf(tmp, "%s%s", dir, file);
  306.     else
  307.     sprintf(tmp, "%s\\%s", dir, file);
  308.     return tmp;
  309. }
  310. static    int    getone(char **ptr)
  311. {
  312.     int c;
  313.     char *p;
  314.  
  315.     p = *ptr;
  316.     c = *(p++);
  317.     if ( iskanji(c) && iskanji2(*p) )
  318.     c = (c << 8) | (unsigned char)*(p++);
  319.     *ptr = p;
  320.     return c;
  321. }
  322. static  char    *wild_rang(char *wild, int fc)
  323. {
  324.     int     wc, ch;
  325.  
  326.     while ( *wild != '\0' ) {
  327.         wc = getone(&wild);
  328.  
  329.         if ( wc == ']' )
  330.             return NULL;
  331.  
  332.         if ( *wild == '-' ) {
  333.             wild++;
  334.             ch = getone(&wild);
  335.             if ( ch == ']' ) {
  336.                 if ( wc <= fc )
  337.                     goto ENDOF;
  338.             } else if ( ch == '\0' )
  339.                 return NULL;
  340.  
  341.             if ( wc <= fc && fc <= ch )
  342.                 goto ENDOF;
  343.  
  344.         } else if ( wc == fc )
  345.             goto ENDOF;
  346.     }
  347.     return NULL;
  348.  
  349. ENDOF:
  350.     while ( *wild != '\0' ) {
  351.         if ( *(wild++) == ']' )
  352.             return wild;
  353.     }
  354.     return NULL;
  355. }
  356. int     wild_mach(char *wild, char *file)
  357. {
  358.     int     wc, fc;
  359.  
  360.     for ( ; ; ) {
  361.         wc = getone(&wild);
  362.         fc = getone(&file);
  363.  
  364.         if ( wc == '\0' )
  365.             return (fc == '\0' ? TRUE:FALSE);
  366.  
  367.         else if ( wc == '*' ) {
  368.             if ( *wild == '\0' )
  369.                 return TRUE;
  370.             for ( file-- ; *file != '\0' ; file++ ) {
  371.                 if ( wild_mach(wild, file) )
  372.                     return TRUE;
  373.             }
  374.             return FALSE;
  375.  
  376.         } else if ( wc == '[' ) {
  377.             if ( (wild = wild_rang(wild, fc)) == NULL )
  378.                 return FALSE;
  379.  
  380.         } else if ( wc != '?' && wc != fc )
  381.             return FALSE;
  382.     }
  383. }
  384.